package com.warom.sdg.webview.jsinterface;

import android.content.Context;
import android.util.Log;

import com.warom.sdg.config.MeasurementPoint;
import com.warom.sdg.config.PlcMeasurementConfig;
import com.warom.sdg.config.PlcMeasurementUtils;
import com.warom.sdg.enums.ModuleType;
import com.warom.sdg.model.ApiResponse;
import com.warom.sdg.model.DeviceType;
import com.warom.sdg.model.PlcDataEntity;
import com.warom.sdg.util.LogUtils;
import com.warom.sdg.webview.BaseWebViewJsInterface;
import com.warom.sdg.webview.WebViewWrapper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * WebView JavaScript接口 - 监测数据
 * 处理气体监测等数据相关的JavaScript调用
 */
public class WebViewJsMonitoringInterface extends BaseWebViewJsInterface {

    private List empList = new ArrayList<>();

    /**
     * 构造函数
     * 
     * @param context        上下文
     * @param webViewWrapper WebView包装类，用于回调
     */
    public WebViewJsMonitoringInterface(Context context, WebViewWrapper webViewWrapper) {
        super(context, webViewWrapper);
    }

    /**
     * 获取气体实时数据
     * 
     * @param args      参数（可指定设备ID）
     * @param requestId 请求ID
     */
    public void getGasRealtimeData(String args, String requestId) {
        executor.execute(() -> getGasRealtimeData(args, result -> handleAsyncResponse(requestId, result)));
    }

    /**
     * 获取气体检测历史数据
     * 
     * @param args      参数（必须指定设备ID、测点地址、开始时间、结束时间）
     * @param requestId 请求ID
     */
    public void getGasHistoryData(String args, String requestId) {
        executor.execute(() -> getGasHistoryData(args, result -> handleAsyncResponse(requestId, result)));
    }

    /**
     * 获取气体实时数据 (异步版本，用于内部实现)
     * 
     * @param argsJson 参数，可指定设备ID，不传则获取所有设备的气体实时数据
     * @param callback 回调函数，接收气体实时数据的JSON字符串
     */
    private void getGasRealtimeData(String argsJson, Consumer<String> callback) {
        try {
            LogUtils.logOperation("气体监测", "查询", "开始获取气体实时数据");

            // 创建结果数据对象
            List<Map<String, Object>> gasDataList = new ArrayList<>();

            // 从配置中获取气体监测模块的测点数据
            Map<DeviceType, List<MeasurementPoint>> gasMonitoringMap = PlcMeasurementConfig.moduleDevicePointsMap.get(
                    ModuleType.GAS_MONITORING);

            if (gasMonitoringMap == null || gasMonitoringMap.isEmpty()) {
                // 如果没有配置气体监测测点，返回空数据但标记为成功
                ApiResponse<List<Map<String, Object>>> response = ApiResponse.success(empList);
                callback.accept(response.toJson());
                return;
            }

            // 注意：实际应用中需要在此处从PLC设备获取测点的实时值并更新value字段
            // 这里直接返回配置中的测点信息，不生成模拟值

            // 使用ApiResponse封装返回结果
            ApiResponse<Map<DeviceType, List<MeasurementPoint>>> response = ApiResponse.success(gasMonitoringMap);
            callback.accept(response.toJson());

        } catch (Exception e) {
            Log.e(TAG, "获取气体监测数据失败", e);
            LogUtils.logError("气体监测", "获取气体监测数据失败", e);
            // 使用标准响应格式返回错误信息
            ApiResponse<String> errorResponse = ApiResponse.error("处理异常: " + e.getMessage());
            callback.accept(errorResponse.toJson());
        }
    }

    /**
     * 获取气体检测历史数据 (异步版本，用于内部实现)
     * 
     * @param argsJson 参数，必须包含：
     *                 deviceId - 设备ID
     *                 address - 测点地址
     *                 startTime - 开始时间戳
     *                 endTime - 结束时间戳
     *                 limit - 可选，限制返回记录数，默认1000
     * @param callback 回调函数，接收历史数据的JSON字符串
     */
    private void getGasHistoryData(String argsJson, Consumer<String> callback) {
        try {
            LogUtils.logOperation("气体监测", "查询历史", "开始获取气体检测历史数据");

            // 解析参数
            Map<String, Object> args = gson.fromJson(argsJson, Map.class);

            // 验证必要参数
            if (!args.containsKey("deviceId") || !args.containsKey("address") ||
                    !args.containsKey("startTime") || !args.containsKey("endTime")) {
                String errorMsg = "缺少必要参数，需要指定设备ID、测点地址、开始时间和结束时间";
                LogUtils.logError("气体监测", "查询历史", new IllegalArgumentException(errorMsg));
                callback.accept(ApiResponse.error(errorMsg).toJson());
                return;
            }

            // 提取参数
            int deviceId = ((Double) args.get("deviceId")).intValue();
            String address = (String) args.get("address");
            long startTime = ((Double) args.get("startTime")).longValue();
            long endTime = ((Double) args.get("endTime")).longValue();
            int limit = args.containsKey("limit") ? ((Double) args.get("limit")).intValue() : 1000;

            // 查询数据库获取历史数据
            dataRepository.getHistoryData(deviceId, address, startTime, endTime, limit,
                    historyData -> {
                        try {
                            // 处理历史数据
                            List<Map<String, Object>> processedData = processHistoryData(historyData, deviceId,
                                    address);

                            // 转换为JSON
                            String jsonResult = gson.toJson(processedData);
                            LogUtils.logOperation("气体监测", "查询历史结果", "获取到 " + processedData.size() + " 条历史记录");

                            // 返回结果
                            callback.accept(jsonResult);
                        } catch (Exception e) {
                            Log.e(TAG, "处理历史数据失败", e);
                            LogUtils.logError("气体监测", "处理历史数据失败", e);
                            callback.accept(ApiResponse.error("处理历史数据失败: " + e.getMessage()).toJson());
                        }
                    },
                    error -> {
                        Log.e(TAG, "查询历史数据失败: " + error);
                        LogUtils.logError("气体监测", "查询历史数据失败", new IllegalArgumentException(error));
                        callback.accept(ApiResponse.error("查询失败: " + error).toJson());
                    });

        } catch (Exception e) {
            Log.e(TAG, "获取气体检测历史数据失败", e);
            LogUtils.logError("气体监测", "获取气体检测历史数据失败", e);

            // 使用标准响应格式
            callback.accept(ApiResponse.error("处理异常: " + e.getMessage()).toJson());
        }
    }

    /**
     * 处理历史数据，添加额外信息
     * 
     * @param historyData 原始历史数据列表
     * @param deviceId    设备ID
     * @param address     测点地址
     * @return 处理后的历史数据
     */
    private List<Map<String, Object>> processHistoryData(List<PlcDataEntity> historyData, int deviceId,
            String address) {
        List<Map<String, Object>> result = new ArrayList<>();

        // 获取测点配置信息
        MeasurementPoint configPoint = null;

        // 查找设备对应的测点配置
        for (DeviceType deviceType : DeviceType.getAllDeviceTypes()) {
            List<MeasurementPoint> points = PlcMeasurementUtils.getMeasurementPoints(
                    ModuleType.GAS_MONITORING, deviceType);

            for (MeasurementPoint point : points) {
                if (point.getAddress().equals(address)) {
                    configPoint = point;
                    break;
                }
            }

            if (configPoint != null)
                break;
        }

        // 遍历历史数据并处理
        for (PlcDataEntity data : historyData) {
            Map<String, Object> item = new HashMap<>();

            // 基本信息
            item.put("deviceId", data.getDeviceId());
            item.put("name", data.getName());
            item.put("address", data.getAddress());
            item.put("type", data.getType()); // 英文名/符号
            item.put("value", data.getValue());
            item.put("unit", data.getUnit());
            item.put("timestamp", data.getTimestamp());

            // 格式化时间
            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            item.put("timeString", sdf.format(new java.util.Date(data.getTimestamp())));

            // 如果找到了配置信息，添加额外配置数据
            if (configPoint != null) {
                item.put("minValue", configPoint.getMinValue());
                item.put("maxValue", configPoint.getMaxValue());
                item.put("warningValue", configPoint.getWarningValue());
                item.put("dangerValue", configPoint.getDangerValue());

                // 计算状态（正常、警告、危险）
                double value = Double.parseDouble(data.getValue());
                if (value >= configPoint.getDangerValue()) {
                    item.put("status", "danger");
                } else if (value >= configPoint.getWarningValue()) {
                    item.put("status", "warning");
                } else {
                    item.put("status", "normal");
                }
            }

            result.add(item);
        }

        return result;
    }

    // 可以添加其他监测数据相关的方法，如：
    // - 获取温湿度数据
    // - 获取能耗数据
    // - 获取通风数据
}